using System;
using System.Windows;
using System.Windows.Media;
using Newtonsoft.Json;

namespace 地图哇哇哇.地图
{
    public class 测试区域 : NotifyPropertyChanged
    {
        public class 地形参数 : NotifyPropertyChanged
        {
            private int _聚集陆地的迭代次数 = 3;
            private double _陆地概率极限 = 0.5;
            private int _陆地极限参数1 = 10;
            private int _陆地极限参数2 = 6;

            public int 聚集陆地的迭代次数
            {
                get => _聚集陆地的迭代次数;
                set => Set(ref _聚集陆地的迭代次数, value);
            }

            public double 陆地概率极限

            {
                get => _陆地概率极限;
                set => Set(ref _陆地概率极限, value);
            }

            public int 陆地极限参数1
            {
                get => _陆地极限参数1;
                set { Set(ref _陆地极限参数1, value); }
            }

            public int 陆地极限参数2
            {
                get => _陆地极限参数2;
                set { Set(ref _陆地极限参数2, value); }
            }
        }

        private 地形参数 _参数 = new 地形参数();

        public 地形参数 参数
        {
            get => _参数;
            set => Set(ref _参数, value);
        }

        private string _名称;
        private string _编号;
        private 地图位置 _位置;
        private 地图尺寸 _尺寸;
        private double _块边长;
        private bool _显示文字;

        public bool 显示文字
        {
            get => _显示文字;
            set => _显示文字 = value;
        }

        public double 块边长
        {
            get => _块边长;
            set => _块边长 = value;
        }

        private Brush _填充画笔;
        private Brush _边框画笔;
        private Thickness _边框粗细;

        private 基块[,] _基块们 = new 基块[0, 0];

        public string 名称
        {
            get => _名称;
            set => _名称 = value;
        }

        public string 编号
        {
            get => _编号;
            set => _编号 = value;
        }

        public 地图位置 位置
        {
            get => _位置;
            set => _位置 = value;
        }

        public Brush 填充画笔
        {
            get => _填充画笔;
            set => _填充画笔 = value;
        }

        public Brush 边框画笔
        {
            get => _边框画笔;
            set => _边框画笔 = value;
        }

        public Thickness 边框粗细
        {
            get => _边框粗细;
            set => _边框粗细 = value;
        }

        [JsonIgnore]
        public 基块[,] 基块们
        {
            get => _基块们;
            set { _基块们 = value ?? new 基块[0, 0]; }
        }

        public 地图尺寸 尺寸
        {
            get => _尺寸;
            set => _尺寸 = value;
        }

        public static Boolean 是空的二维吗(基块[,] arr)
        {
            return arr.Rank == 2 && arr.GetLength(0) == 0 && arr.GetLength(1) == 0;
        }

        public void 陆地聚集化()
        {
            var A1 = 基块们.GetLength(0);
            var B1 = 基块们.GetLength(1);
            for (int q = 0; q < 参数.聚集陆地的迭代次数; q++)
            {
                for (int i = 0; i < B1; i++)
                {
                    for (int j = 0; j < A1; j++)
                    {
                        var jk = 基块们[j, i];
                        int 陆地 = 0;
                        for (int k = i - 2; k < i + 2; k++)
                        {
                            for (int l = j - 2; l < j + 2; l++)
                            {
                                if (k >= 0 && k < B1 && l >= 0 && l < A1)
                                {
                                    if (基块们[l, k].地形类型 == 地形类型.陆地)
                                    {
                                        陆地++;
                                    }
                                }
                            }
                        }

                        if (陆地 > 参数.陆地极限参数1)
                            jk.地形类型 = 地形类型.陆地;
                        else if (陆地 < 参数.陆地极限参数2)
                            jk.地形类型 = 地形类型.无;
                    }
                }
            }
        }

        public void 随机地形()
        {
            if (基块们 == null)
                return;
            var A1 = 基块们.GetLength(0);
            var B1 = 基块们.GetLength(1);
            var ran = new Random(Guid.NewGuid().GetHashCode());
            for (int i = 0; i < B1; i++)
            {
                for (int j = 0; j < A1; j++)
                {
                    var jk = 基块们[j, i] = new 基块();
                    jk.位置 = new Point(尺寸.格长度 * j, 尺寸.格长度 * i);
                    jk.尺寸 = new Size(尺寸.格长度, 尺寸.格长度);
                    var d = ran.NextDouble();
                    jk.地形类型 = d >= (1 - 参数.陆地概率极限) ? 地形类型.陆地 : 地形类型.无;
                }
            }

            陆地聚集化();
            /*for (int i = 0; i < B1; i++)
            {
                for (int j = 0; j < A1; j++)
                {
                    var jk = 基块们[j, i];
                    if (jk.地形类型 == 地形类型.无)
                    {
                        var d = ran.NextDouble();
                        if (d > 0.9)
                        {
                            jk.地形类型 = 地形类型.河流;
                        }
                        else if (d > 0.7)
                        {
                            jk.地形类型 = 地形类型.湖泊;
                        }
                        else
                        {
                            jk.地形类型 = 地形类型.其它;
                        }
                    }
                }
            }*/
        }

        public DrawingGroup 出图()
        {
            DrawingGroup dg = new DrawingGroup();
            var frame = new Rect(位置.像素位置, 尺寸.像素大小);
            var framegd = new GeometryDrawing(填充画笔, new Pen(边框画笔, 1),
                new RectangleGeometry(frame));
            //dg.Children.Add(framegd);
            var dg基块们 = new DrawingGroup();
            var gg陆地 = new GeometryGroup();
            var a = 基块们.GetLength(0);
            var b = 基块们.GetLength(1);
            for (int i = 0; i < b; i++)
            {
                for (int j = 0; j < a; j++)
                {
                    var jk = 基块们[j, i];
                    if (jk == null) continue;
                    var jk层位置 = new Point(位置.像素位置.X + jk.位置.X, 位置.像素位置.Y + jk.位置.Y);
                    var jkrect = new RectangleGeometry(new Rect(jk层位置, jk.尺寸));

                    Brush br = null;
                    switch (jk.地形类型)
                    {
                        case 地形类型.陆地:
                            br = 地形.陆地.材质画笔;
                            gg陆地.Children.Add(jkrect);
                            break;
                        case 地形类型.湖泊:
                            br = 地形.湖泊.材质画笔;
                            break;
                        case 地形类型.河流:
                            br = 地形.河流.材质画笔;
                            break;
                        case 地形类型.其它:
                            break;
                        case 地形类型.无:
                            break;
                        case 地形类型.耕地:
                            break;
                        case 地形类型.林地:
                            break;
                        case 地形类型.山地:
                            break;
                        case 地形类型.水域:
                            break;
                        case 地形类型.海洋:
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }

                    var rgd = new GeometryDrawing(br, null, jkrect);
                    dg基块们.Children.Add(rgd);
                }
            }

            /*var pg陆地 = PathGeometry.CreateFromGeometry(gg陆地).GetFlattenedPathGeometry();
            var figures陆地 = pg陆地.Figures;
            var dg陆地s = new DrawingGroup();
            var cl = ColorGenerator.GetColorsCollection(figures陆地.Count);
            for (int i = 0; i < figures陆地.Count; i++)
            {
                var figure = figures陆地[i];
                var aas = new
                    PathGeometry
                    (new
                        [] {figure});
                dg陆地s.Children.Add(new GeometryDrawing(new SolidColorBrush(cl[i]),
                    null, aas));
            }*/

            var gg陆地轮廓 = gg陆地.GetOutlinedPathGeometry();
            var dg陆地轮廓s = new DrawingGroup();
            var figures陆地轮廓 = gg陆地轮廓.Figures;
            var cl = ColorGenerator.GetColorsCollection(figures陆地轮廓.Count);
            for (int i = 0; i < figures陆地轮廓.Count; i++)
            {
                var figure = figures陆地轮廓[i];
                var aas = new
                    PathGeometry
                    (new
                        [] {figure});
                dg陆地轮廓s.Children.Add(new GeometryDrawing(new SolidColorBrush(cl[i]),
                    null, aas));
            }

            dg.Children.Add(dg基块们);
         dg.Children.Add(dg陆地轮廓s);
            if (显示文字)
            {
                var run = DrawingHelper.GetGlyphRun(
                    是空的二维吗(基块们) ? "空区域" : $"{名称}({a},{b})@{尺寸.格长度}", 12, Datar.Simhei, frame,
                    out var w, true);
                var grun = new GlyphRunDrawing(
                    名称.Equals("第1区域")
                        ? Brushes.OrangeRed
                        : new SolidColorBrush(Color.FromArgb(147, 173, 255, 47)), run);
                dg.Children.Add(grun);
            }

            return dg;
        }
    }
}